package klog

import (
	"fmt"
	"gitee.com/klogsdk/klog-go-sdk/credentials"
	"math/rand"
	"net"
	"net/http"
	"time"
)

// DefaultChainCredentials is a Credentials which will find the first available
// credentials Value from the list of Providers.
//
// This should be used in the default case. Once the type of credentials are
// known switching to the specific Credentials will be more efficient.
var DefaultChainCredentials = credentials.NewChainCredentials(
	[]credentials.Provider{
		&credentials.EnvProvider{},
		&credentials.SharedCredentialsProvider{Filename: "", Profile: ""},
	})

const (
	CompressMethodNone = "none"
	CompressMethodLz4  = "lz4"
)

type ClientOptions struct {
	AccessKey   string
	SecretKey   string
	Credentials *credentials.Credentials
	Endpoint    string
	HTTPClient  *http.Client
	Logger      Logger
	LogLevel    int

	// 发送日志的协程数
	WorkerNum           int
	CompressMethod      string
	DropIfPoolNotExists bool
	RateLimit           int
	DownSampleRate      float64
	MaxRetries          int

	// 标识上报的app名字，非必填
	AppName string

	// 机器ID，取值范围[1, 1023]，用于生成日志ID。如果缺省，会随机生成一个机器ID。
	MachineId int
}

func (o *ClientOptions) init() {
	if o.Credentials == nil {
		if o.AccessKey != "" && o.SecretKey != "" {
			o.Credentials = credentials.NewStaticCredentials(o.AccessKey, o.SecretKey, "")
		} else {
			o.Credentials = DefaultChainCredentials
		}
	}

	if o.LogLevel == 0 {
		o.LogLevel = LevelInfo
	}

	if o.Logger == nil {
		o.Logger = GetStdLogger(o.LogLevel)
	}

	if o.HTTPClient == nil {
		o.HTTPClient = &http.Client{
			Transport: &http.Transport{
				Proxy: http.ProxyFromEnvironment,
				DialContext: (&net.Dialer{
					Timeout:   10 * time.Second,
					KeepAlive: 30 * time.Second,
				}).DialContext,
				MaxIdleConns:          100,
				IdleConnTimeout:       30 * time.Second,
				TLSHandshakeTimeout:   10 * time.Second,
				ExpectContinueTimeout: 1 * time.Second,
			},
			Timeout: 10 * time.Second,
		}
	}

	if o.WorkerNum == 0 {
		o.WorkerNum = 2
	}

	if o.CompressMethod != CompressMethodNone {
		o.CompressMethod = CompressMethodLz4
	}

	o.AppName = fmt.Sprintf("%s_%s", SDKVersion, o.AppName)

	if o.MachineId <= 0 || o.MachineId > 1023 {
		o.MachineId = rand.Intn(1023) + 1
	}
}
